
#include <google/protobuf/descriptor.h>
#include <google/protobuf/service.h>

#include "zrpc/rpc/rpc_server.h"
#include "zrpc/base/log.h"

namespace zrpc {
RpcServer::RpcServer(EventLoop *loop, const std::string &ip, uint16_t port)
    : server_(loop, ip, port, nullptr) {
  server_.SetConnectionCallback(
      std::bind(&RpcServer::ConnectCallback, this, std::placeholders::_1));
}

void RpcServer::RegisterService(::google::protobuf::Service *service) {
  const ::google::protobuf::ServiceDescriptor *desc = service->GetDescriptor();
  services_[desc->full_name()] = service;
}

void RpcServer::Start() { server_.Start(); }

void RpcServer::ConnectCallback(const std::shared_ptr<TcpConnection> &conn) {
  if (conn->Connected()) {
    RpcChannelPtr channel(new RpcChannel(conn));
    channel->SetServices(&services_);
    conn->SetMessageCallback(std::bind(&RpcChannel::OnMessage, channel.get(),
                                       std::placeholders::_1,
                                       std::placeholders::_2));
    conn->SetContext(channel);
  } else {
    conn->ResetContext();
  }
}
}  // namespace zrpc